#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>

#include "main.h"
#include "sighandler.h"


static handler_cb sighandler_cb = NULL;
static sigset_t set;
bool accept_signals = false;

static const char *fmt = "recieved signal %d ( %s )";
#define SGNLSTR_STR(str) signo, str

static void
sgnl(int signo)
{
  switch (signo)
  {
    case SIGHUP:
      I(fmt, SGNLSTR_STR("SIGHUP"));
      break;
    case SIGINT:
      I(fmt, SGNLSTR_STR("SIGINT"));
      break;
    case SIGTERM:
      I(fmt, SGNLSTR_STR("SIGTERM"));
      break;
    case SIGUSR1:
      I(fmt, SGNLSTR_STR("SIGUSR1"));
      break;
    case SIGUSR2:
      I(fmt, SGNLSTR_STR("SIGUSR2"));
      break;
    default:
      I(fmt, SGNLSTR_STR("NOT HANDLED"));
      return;
      break;
  }
  if (sighandler_cb && accept_signals)
  {
    sighandler_cb(signo);
  } else if (!accept_signals) {
    I2("ignoring signal ..");
  }
}

void
init_sighandler(handler_cb __sighandler)
{
  static struct sigaction sa;

  sighandler_cb = __sighandler;

  sa.sa_handler = sgnl;
  sa.sa_flags = SA_RESTART;
  sigaction(SIGHUP, &sa, NULL);
  sigaction(SIGINT, &sa, NULL);
  sigaction(SIGTERM, &sa, NULL);
  sigaction(SIGUSR1, &sa, NULL);
  sigaction(SIGUSR2, &sa, NULL);

  sigemptyset(&set);
  sigaddset(&set, SIGINT);
  sigaddset(&set, SIGHUP);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGUSR1);
  sigaddset(&set, SIGUSR2);
  sigprocmask(SIG_UNBLOCK, &set, NULL);
}

#ifdef ENABLE_PTHREADS
int
pthread_setsigs(void)
{
  return (pthread_sigmask(SIG_BLOCK, &set, NULL));
}
#endif

